using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Reflection;
using DevExpress.XtraGrid;
using DevExpress.XtraGrid.Columns;
using DevExpress.XtraGrid.Views.BandedGrid;
using DevExpress.XtraGrid.Views.Grid;

namespace Comteck.Winforms {
  /// <summary>
  /// 
  /// </summary>
  public static partial class GridControlExtesions {

    /// <summary>
    /// 禁用全部的编辑功能
    /// </summary>
    /// <param name="grid"></param>
    /// <returns></returns>
    public static GridView DisableAllColumnsEdit(this GridView grid) {
      foreach (GridColumn column in grid.Columns) {
        column.OptionsColumn.AllowEdit = false;
      }

      return grid;
    }

    /// <summary>
    /// 全部不选中
    /// </summary>
    /// <param name="grid"></param>
    /// <returns></returns>
    public static GridView UnSelectRowAll(this GridView grid) {
      for (var i = 0; i < grid.RowCount; i++) {
        grid.UnselectRow(i);
      }

      return grid;
    }

    /// <summary>
    /// 根据指定类型动态添加列
    /// </summary>
    /// <param name="grid"></param>
    /// <param name="type"></param>
    public static void AddListHeads(this GridView grid, Type type) {
      var propertyArray = type.GetTypeInfo().GetProperties(BindingFlags.GetProperty
        | BindingFlags.Public | BindingFlags.Instance);

      // 无属性
      if (propertyArray.IsNullOrEmpty()) {
        return;
      }

      // 对属性进行排序
      propertyArray = OrderBy(propertyArray);

      // 
      foreach (var prop in propertyArray) {
        // 标题
        var description = prop.GetCustomAttributes(true).OfType<DescriptionAttribute>().FirstOrDefault()?.Description;

        // 是否可见
        var visible = prop.GetCustomAttributes(true).OfType<BrowsableAttribute>().FirstOrDefault()?.Browsable ?? true;

        // 是否只读
        var isReadOnly = prop.GetCustomAttributes(true).OfType<ReadOnlyAttribute>().FirstOrDefault()?.IsReadOnly ?? false;

        var column = new GridColumn() {
          Caption = description.IsNullOrEmpty() ? prop.Name : description,
          FieldName = prop.Name,
          Name = $"col_{prop.Name}",
          Visible = visible,
        };

        column.OptionsColumn.AllowEdit = !isReadOnly;

        grid.Columns.Add(column);
      }
    }

    /// <summary>
    /// 动态添加汇总栏
    /// </summary>
    /// <param name="grid"></param>
    /// <param name="summaryDic"></param>
    public static void AddSummarys(this GridView grid, List<GridColumnSummaryItem> summaryList) {
      if (summaryList.IsNullOrEmpty()) {
        grid.OptionsView.ShowFooter = false;
        return;
      }

      // 显示底部栏
      grid.OptionsView.ShowFooter = true;

      // 循环
      foreach (var summaryItem in summaryList) {
        try {
          var column = grid.Columns[summaryItem.FieldName];

          column.Summary.AddRange(new GridSummaryItem[] { summaryItem });
        } catch {
        }
      }
    }

    /// <summary>
    /// 动态添加掩码
    /// </summary>
    /// <param name="grid"></param>
    /// <param name="columnDic"></param>
    public static void AddDisplayMask(this GridView grid, Dictionary<string, string> columnDic) {
      if (columnDic == null || columnDic.Count == 0) { return; }
      
      foreach (GridColumn column in grid.VisibleColumns) {
        if (columnDic.TryGetValue(column.FieldName, out string value)) {
          column.DisplayFormat.FormatString = value;
        }
      }
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="propertyInfos"></param>
    /// <returns></returns>
    private static Dictionary<PropertyInfo, TransferOrderAttribute> GetTransferOrder(PropertyInfo[] propertyInfos) {
      var dic = new Dictionary<PropertyInfo, TransferOrderAttribute>();

      foreach (var prop in propertyInfos) {
        dic.Add(prop, prop.GetCustomAttributes(true).OfType<TransferOrderAttribute>().FirstOrDefault());
      }

      return dic;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="properties"></param>
    /// <returns></returns>
    private static PropertyInfo[] OrderBy(PropertyInfo[] properties) {
      var result = new List<PropertyInfo>();

      // 查找全部由排序属性的
      var propList1 = properties.Where(prop => prop.GetCustomAttributes(true).OfType<TransferOrderAttribute>().Any())
        .OrderBy(prop => prop.GetCustomAttributes(true).OfType<TransferOrderAttribute>().FirstOrDefault()?.Order)
        .ToList();

      var propList2 = properties.Where(prop => propList1.Any(x => x == prop) == false).ToList();

      return propList1.Concat(propList2).ToArray();
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="gridView"></param>
    /// <returns></returns>
    public static GridView SetAppearanceColor(this GridView gridView) {
      //// 偶数行背景色，如果BackColor与BackColor2颜色不同，则显示为渐变色




      //// 奇数行背景色





      gridView.Appearance.SelectedRow.BackColor = Color.MediumSlateBlue;
      gridView.Appearance.SelectedRow.ForeColor = Color.Black;
      gridView.Appearance.SelectedRow.Options.UseBackColor = true;
      gridView.Appearance.SelectedRow.Options.UseForeColor = true;

      gridView.Appearance.FocusedRow.BackColor = Color.MediumSlateBlue;
      gridView.Appearance.FocusedRow.ForeColor = Color.Black;
      gridView.Appearance.FocusedRow.Options.UseBackColor = true;
      gridView.Appearance.FocusedRow.Options.UseForeColor = true;

      return gridView;
    }

    /// <summary>
    /// 动态创建的控件释放并且清空
    /// </summary>
    /// <param name="gv"></param>
    public static void ClearAndDispose(this GridView gv, bool leaveBand = false) {
      // 清空
      var toDisposeColumnList = gv.Columns.ToArray();
      for (var i = 0; i < toDisposeColumnList.Length; i++) {
        toDisposeColumnList[i]?.Dispose();
        toDisposeColumnList[i] = null;
      }
      toDisposeColumnList = null;

      if (!leaveBand) {
        if (gv is BandedGridView bandedGrid) {
          var bandList = bandedGrid.Bands.ToArray();
          for (var i = 0; i < bandList.Length; i++) {
            bandList[i]?.Dispose();
            bandList[i] = null;
          }
          bandList = null;
        }
      }

      gv.Columns.Clear();
    }

    /// <summary>
    /// 动态创建的控件释放并且清空
    /// </summary>
    /// <param name="gv"></param>
    public static void ClearAndDispose(this GridBand band) {
      // 清空
      var count = band.Columns.Count;
      for (var i = count - 1; i >= 0; i--) {
        band.Columns[i].Dispose();
      }
      band.Columns.Clear();
    }

  }
}
